Specifying Coherent Refactoring of Software Artefacts with Distributed Graph Transformations

نویسندگان

  • Paolo Bottoni
  • Francesco Parisi-Presicce
  • Gabriele Taentzer
چکیده

class AbstractPlayer { protected ContentSource source; private Description preferences; private Environment env; protected abstract ContentSource findSource(); protected abstract void setEnvironment(); protected void playContent() { source = findSource(); Content toPlay = source.provideContent(this); setEnvironment(); toPlay.play(env); } Description getPreferences() { return preferences; } void setPreferences(Description desc) { preferences = desc; } } class Audio extends AbstractPlayer { ContentSource findSource() { // code from findMusicSource } void setEnvironment() { // previous code used to set env } } interface ContentSource { Content provideContent(AbstractPlayer requester); } class MusicSource implements ContentSource { Content provideContent(AbstractPlayer requester) { Description desc = requester.getPreferences(); // previous code from provideMusic exploiting desc; } } interface Content { void play(Environment env); } class Music implements Content { // same implementation as before } class Environment { // same implementation as before } 3. The Formal Background The algebraic approach to graph transformation (Corradini et.al., 1997) is the formal basis for our work on refactoring, as graphs are natural means to represent code and model structures. Their modification is performed by applying graph rules. To handle model and code-related graphs in a separate but consistent way, we apply concepts of distributed graph transformation. Finally, the concept of transformation units is used to obtain a global control on structured graph manipulations, useful to specify complex refactorings. 3.1 Graph Transformation Graphs are often used as abstract representation of code and diagrams, e.g. of UML diagrams. Formally, a graph consists of a set of vertices V and a set of edges E such that each edge e in E has a source and a target vertex s(e) and t(e) in V, resp. Each vertex and edge may be attributed by some data value or object, formally expressed by elements of an algebra on some algebraic signature Σ. The theory of graph transformation is largely independent of the notion of graph, so that one can be chosen which best reflects domain-specific structures. Here, we consider typed attributed graphs. Graph manipulation is performed by the so-called double-pushout approach to graph transformation, DPO (Corradini et.al., 1997), based on category theory. Using typed graphs, structural aspects occur on two levels: the type level (modelled by a type graph T) and the instance level (modelled by an instance graph). An instance graph is correctly typed if it can be mapped in a structure-preserving manner to T, formally expressed by a graph homomorphism. A graph rule r: L → R consists of a pair of T-typed instance graphs L, R such that the union L ∪ R is defined. That means graph objects which occur in both, L and R, have the same type and attributes and, if edges, the same source and target vertices. The left-hand side L represents the pre-conditions of a modification, while the right-hand side R shows the effect of the modification. Vertex identity is expressed via names, while edge identity is deduced from the identity of the connected vertices. Additionally, graph rules comprise attribute computations where left-hand sides may contain constants or variables of set X, while right-hand sides capture the proper computations, denoted as elements of term algebra TΣ (X). A rule may also contain a set of negative application conditions (NAC), expressing graph parts that must not exist for the rule to be applicable. NACs are finite sets of graphs NAC={Ni| L⊆ Ni, i ≥0 }, expressing the conjunction of basic conditions, and can refer to values of attributes (Fischer et.al, 1999). For a rule to be applicable, none of the prohibited graph parts Ni L present in a NAC may occur in the host graph G so that this occurrence is compatible with a rule match m. A match is an injective graph homo-morphism m: L∪ R → G ∪ H, such that m(L) ⊆ G and m(R) ⊆ H, i.e. the left-hand side of the rule is embedded into G and the right-hand side into H. In this paper we use dotted lines to denote NACs. Non-connected NACs denote different negative application conditions (see Figure 14 for an example). A graph transformation from a graph G to a graph H, p(m): G ⇒ H, is given by a rule r and a match m with m(L R) = G H and m(R L) = H G, i.e. precisely that part of G is deleted which is matched by graph objects of L not belonging to R and symmetrically, that part of H is added which is matched by new graph objects in R. Operationally, the application of a graph rule is performed as follows: First, find an occurrence of L in graph G. Second, remove all the vertices and edges from G matched by L R. Make sure that the remaining structure D= G-m(L-R) is still a proper graph, i.e. no edge is left which dangles because its source or target vertex has been deleted. In this case, the dangling condition is violated and the application of the rule at match m is not possible. Third, glue D with R-L to obtain graph H. A typed graph transformation system GTS=(T,I,R) consists of a type graph T and a finite set R of graph rules with all left and right-hand sides typed over T. GTS defines formally the set of all possible graphs by Graphs(GTS)={G|I ⇒R G } where G ⇒R H ≡ G ⇒r1(m1) H1 ... ⇒rn(mn) Hn = H with r1, ..., rn in R and n >= 0. It follows from the theory that each graph G is correctly typed. 3.2 Distributed Graph Transformation Distributed graph transformation (Fischer et. al., 1999) is graph transformation structured at two abstraction levels: the network and the object level. The network level contains the description of a system’s architecture by a network graph, and its dynamic reconfiguration by network rules. At the object level, graph transformations manipulate local object structures. To describe a synchronized manipulation on distributed graphs, a combination of graph transformations on both levels is needed. A distributed graph consists of a network graph where each network vertex is refined by a local graph. Network edges are refined by graph homomorphisms on local graphs which describe how the local graphs are interconnected. Each local graph may be typed differently, only restricted by the fact that an interface type graph is fully mapped to all connected local type graphs. In the following, we use distributed graphs where the network graphs consist of three vertices: for the model, for the code and for their interface. Furthermore, two network edges are needed, starting from the interface vertex and going to the model and code vertices, respectively. The corresponding refinement graphs are called model graph, code graph and interface graph. The interface graph holds exactly that subgraph which describes the correspondences between the other two local graphs. A distributed graph rule r is defined by a network rule n – which is a normal graph rule – together with a set S of local rules – graph rules on local graphs – for all those network vertices which are preserved. Each preserved network edge guarantees a compatibility between the corresponding local rules. The rules must also be consistent with common attribute values. In the following, the network rules will always be identical, meaning that the network is not changing. Two local rule applications on the model and the code graph will be synchronized by applying a common subrule on their interface graph. The rules in the following figures are local rules where we will use grey levels to indicate subrule parts. We introduce two operators to assemble a distributed rule from local ones: asOftenAsPossible means to apply a local rule as often as possible at different matches in parallel, while || just denotes the distributed application of rules. 3.3 Transformation Units Transformation units (Kreowski et al., 1997) are used to control rule application, with the control condition specified by expressions over rules. The notion is defined independently of any given approach to graph transformation. It just assumes a certain graph transformation approach A consisting of a class of graphs G, a class of rules R, a rule application operator yielding a binary relation on graphs for every rule of R, a class E of graph class expressions, and a class C of control conditions. A transformation unit consists of: an initial and a terminal graph class expression (defining valid input and output graphs); a set of rules; a set of references to other transformation units, whose rules can be used in the current one; and a control condition over C describing how rules can be applied. Typically, C contains expressions on sequential application of rules and units, as well as conditions and loops, e.g. applying a rule as long as possible. We adopt here the syntax for control expressions presented in (Koch, Parisi Presicce, 2002). In this paper, we apply transformation units to distributed graph transformation, so that G is the class of distributed graphs, R the class of distributed rules, and the DPO way of rule application, as defined in (Fischer et.al., 1999), is the rule application operator. We adopt the class C described in (Koch, Parisi-Presicce, 2002), while the class E is not needed here and can trivially be left empty to indicate that no special initial and terminal graph classes need be specified. We relate rule expressions to graph rules by giving names to rules and passing parameters to them, to be matched to specific attributes of some vertex. By this mechanism, we can restrict the application of rules to those elements which carry an actual reference to the code to be refactored. To this end, the rules presented in the transformation units are meant as rule schemes to be instantiated to actual rules, assigning the parameters as values of the indicated attributes. 4. Refactoring by Graph Transformation We present the general setting of refactoring by graph transformation and analyse a sample refactoring which involves transformation of the code and more than one UML diagram. Furthermore, we show the use of transformation units over distributed graph transformations to enforce synchronization and atomicity of the transformations in different diagrams. 4.1 Graph Representation of Diagrams and Code The abstract representations of code and UML models are given in the form of graphs, obeying the constraints imposed by a type graph. For the code, we refer to the JavaML definition of an abstract syntax for Java (Badros, 2000), and we consider the type graph provided by its DTD. Indeed, any JavaML document is structured as a tree, i.e. a special kind of graph where an XML element is represented by a typed vertex and its attributes by vertex attributes. The graph edges show the sub-element relation and are untyped and not attributed. We call this graph the code graph. For UML (OMG, 2002), the abstract syntax of the UML metamodel provides the type graph to build an abstract representation of the diagram, that we call the model graph. As an example, Figure 7 shows the code graph for class Audio. Due to reasons of space, we omit the representation of the fields ms and env and of the method findMusicSource. Similarly, Figure 8 presents the model graph for the class diagram of Figure 5a (without dependencies). Here and in the following figures, only the important fields of model elements are shown. Details of model elements occurring in more than one figure are shown only in one. One can notice that the vertices that would be directly connected to a class vertex in the code graph, appear in the model graph as feature elements for which the class is an owner. Figures 9 and 10 present the components of the model graph for the sequence and activity diagrams of Figure 5. c1‘: class name = „Audio“ : java-class-file m1‘: method name= „playMusic“ id = „Audio:mth1“ visibility = protected : type name= „void“ primitive = true : assignment-expr op = „=„ c6‘: send message= „findMusicSource“ : block a1‘: field name= „preferences“ visibility = public : type name= „MusicDescription“ : lvalue a2‘: var-set name= „ms“ : local-variable name = „toPlay“ id = „Audio:var1“ : type name= „Music“ c7‘: send message= „provideMusic“ : target a2‘: var-ref name= „ms“ : arguments o8‘: this 1 2 : java-source-program c8‘: send message= „play“ : target o6‘: var-ref name= „toPlay“ idref=„Audio:var1“ i1‘: arguments 3 o5‘: var-ref name= „env“ Figure 7. A part of the code graph for the first version of the code of class Audio. The model graphs, though presented here separately, are construed as different views on one large graph representing the whole model. Indeed, the behavioral diagrams are associated with the model elements which own or contribute to the model’s behavior. As an example, object m1:Method for playMusic appears in Figure 8 as a behavioral feature of class Audio, and in Figure 10 as the element whose behavior is defined by the component of the model graph for activity diagrams. Conversely, object o2:operation appears as the specification for the same method in Figure 8, and as the operation for a CallOperationAction object in Figure 9. In the next section, we will show how transformation units for distributed transformations can be used to modify both graphs, code and model, in a coordinated way. This coordination is based on the existence of correspondences between elements in the two graphs, indicated by similar names (e.g. “c1’ ” in Figure 7 and “c1” in Figure 8) and further discussed in Section 5. m1:Method name= „playMusic“ visibility=#protected c1:Class name= „Audio“ c2:Class name= „MusicDescription“ a1:Attribute name= „preferences“ visibility= #public m2:Method name= „findMusicSource“ visibility=#protected c4:Class name= „Environment“ c3:Class name= „MusicSource“ m3:Method name= „provideMusic“ visibility=#public c5:Class name= „Music“ :Method name= „play“ visibility=#protected :Parameter name= „env“ kind=#in :Association :AssociationEnd a3:AssociationEnd name= „env“ visibility=#private :AssociationEnd

برای دانلود رایگان متن کامل این مقاله و بیش از 32 میلیون مقاله دیگر ابتدا ثبت نام کنید

ثبت نام

اگر عضو سایت هستید لطفا وارد حساب کاربری خود شوید

منابع مشابه

Formalizing refactorings with graph transformations

The widespread interest in refactoring —transforming the source-code of an objectoriented program without changing its external behaviour— has increased the need for a precise definition of refactoring transformations and their properties. In this paper we explore the use of graph rewriting for specifying refactorings and their effect on programs. We introduce a graph representation for program...

متن کامل

Coordinated Distributed Diagram Transformation for Software Evolution

We present an approach to maintaining consistency between code and specification during refactoring, where a specification comprises several UML diagrams of different types. Code is represented as a flowgraph, and the flowgraph and UML diagrams constitute different views of a software system. A refactoring is modelled as a set of distributed graph transformations, organized into transformation ...

متن کامل

Shaped Generic Graph Transformation

Since the systematic evolution of graph-like program models has become important in software engineering, graph transformation has gained much attention in this area. For specifying model evolution concisely, graph transformation rules should be as expressive as possible. The generic rules proposed in this paper may contain placeholders for graphs of varying number and shape. Expansion of these...

متن کامل

ormalizing Refactorings ith Graph Transformations

he widespread interest in refactoring —transforming the source-code of an objectriented program without changing its external behaviour— has increased the need or a precise definition of refactoring transformations and their properties. In this aper we explore the use of graph rewriting for specifying refactorings and their effect n programs. We introduce a graph representation for programs and...

متن کامل

Program Graph Transformation

Graph transformation, a branch of theoretical computer science, is about the definition of graph languages by grammars, and the study of computations on graphs by rewrite rules. In this paper, we sketch a software engineering problem – the refactoring of object-oriented software – and indicate how graph grammars and graph rewrite rules can be extended for specifying and implementing refactoring...

متن کامل

On the Use of Graph Transformations for Model Refactoring

Model-driven software engineering promotes the use of models and transformations as primary artifacts. Several formalisms can be used for the specification of model transformations. We propose to represent models as graphs, and model transformations as graph transformations. In particular, we focus on the activity of model refactoring, and show how graph transformation theory can provide formal...

متن کامل

ذخیره در منابع من


  با ذخیره ی این منبع در منابع من، دسترسی به آن را برای استفاده های بعدی آسان تر کنید

عنوان ژورنال:

دوره   شماره 

صفحات  -

تاریخ انتشار 2003